﻿using BepInEx;
using Cysharp.Threading.Tasks;
using HarmonyLib;
using LBoL.ConfigData;
using LBoL.Core;
using LBoL.Core.Cards;
using LBoL.Presentation;
using LBoL.Presentation.UI.Panels;
using LBoL.Presentation.UI.Widgets;
using MBP.ModBase;
using Newtonsoft.Json;
using SimpleJSON;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using UnityEngine;
using UnityEngine.UI;

namespace ModBasePlugin
{
    [BepInPlugin(ID, "Mod基础插件", VERSION)]
    public class PluginManager : BaseUnityPlugin
    {
        public const string ID = "probe.lbol.mod00.ModBasePlugin";
        public const string VERSION = "0.1.0";
        public const string ModsFolderPath = "./Mods";
        public static BepInEx.Logging.ManualLogSource logger;
        public static bool IsInitLocalize = false;

        public static Type TypeFactory = Assembly.Load("LBoL.Core").GetType("LBoL.Core.TypeFactory`1");
        public static Type TypeFactory_Card = TypeFactory.MakeGenericType(typeof(Card));

        #region Managers
        public static ModCardManager CardManager { get; } = new ModCardManager();
        #endregion
        /// <summary>
        /// 所有LBoLMod
        /// </summary>
        public static List<ModInfo> ModInfos = new List<ModInfo>();

        public void Awake()
        {
            logger = Logger;
            #region Harmony

            var harmony = new Harmony(ID);
            harmony.PatchAll(Assembly.GetExecutingAssembly());

            #endregion
            // 读取Mods文件夹下所有LBoLMod.json.
            getLBolJsons();
            ModCardManager.logger = Logger;

            CardManager.Init();

        }

        static void ShowMe()
        {

        }

        private void getLBolJsons()
        {
            if (!Directory.Exists(ModsFolderPath))
            {
                Directory.CreateDirectory(ModsFolderPath);
            }

            DirectoryInfo dir = new DirectoryInfo(ModsFolderPath);
            //找到Mods目录下的所有Mod
            DirectoryInfo[] modsDir = dir.GetDirectories();
            foreach (DirectoryInfo d in modsDir)
            {
                var file = d.GetFiles().FirstOrDefault(f => f.Name.Equals("LBoLMod.json"));
                if (file != null)
                {
                    var json = file.OpenText().ReadToEnd();
                    //var modinfo = JsonConvert.DeserializeObject<ModInfo>(json);
                    var jsonNode = JSON.Parse(json);
                    var modInfo = new ModInfo(jsonNode);
                    modInfo.mod_path = file.Directory.FullName;
                    logger.LogWarning("加载了MOD:" + modInfo.name);
                    ModInfos.Add(modInfo);
                }
            }
        }


        [HarmonyPatch(typeof(CardConfig),
            "Load",
            new Type[] { typeof(byte[]) })]
        class CardConfig_Load
        {
            public static void Postfix()
            {
                var t = Traverse.Create(typeof(CardConfig));
                var _data = t.Field("_data");
                var _IdTable = t.Field("_IdTable");

                var modcs = CardManager.GetCardConfigs(_data.GetValue<CardConfig[]>().Length);
                foreach (var c in modcs)
                {
                    logger.LogWarning(c);
                }

                _data.SetValue(_data.GetValue<CardConfig[]>().Concat(modcs).ToArray());
                _IdTable.SetValue(_data.GetValue<CardConfig[]>().ToDictionary((CardConfig elem) => elem.Id));
            }
        }

        /// <summary>
        /// 你不仁我也不义，暴力织入数据！
        /// </summary>
        [HarmonyPatch(typeof(GameMaster),
            "StartupEnterMainMenu",
            new Type[] { typeof(int) })]
        class GameMaster_StartupEnterMainMenu
        {
            static void Prefix()
            {
                #region Card
                var Card_TypeDict = TypeFactory.MakeGenericType(typeof(Card))
                    .GetField("TypeDict", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static);

                var Card_FullNameTypeDict = TypeFactory.MakeGenericType(typeof(Card))
                    .GetField("FullNameTypeDict", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static);

                var Card_TypeLocalizers = TypeFactory.MakeGenericType(typeof(Card))
                    .GetField("_typeLocalizers", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static);

                var Card_FailureTable = TypeFactory.MakeGenericType(typeof(Card))
                    .GetField("_failureTable", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static);


                // Type:织入mod卡牌类
                var typeDic = Card_TypeDict.GetValue(null) as Dictionary<string, Type>;
                var fullnameTypeDic = Card_FullNameTypeDict.GetValue(null) as Dictionary<string, Type>;
                foreach (var c in CardManager.GetModCardTypes())
                {
                    if (typeDic.TryGetValue(c.Name,out _))
                    {
                        //  mod优先，存在即替换
                        typeDic[c.Name] = c;
                        fullnameTypeDic[c.FullName] = c;
                    }
                    else
                    {
                        typeDic.Add(c.Name, c);
                        fullnameTypeDic.Add(c.FullName, c);
                    }
                }
                //logger.LogWarning("-----typeDic-----");
                //var json = JsonConvert.SerializeObject(typeDic);
                //logger.LogWarning(json);

                Card_TypeDict.SetValue(null, typeDic);
                Card_FullNameTypeDict.SetValue(null, fullnameTypeDic);

                // Localizers:织入mod本地化
                // _failureTable先不考虑
                var localizers = Card_TypeLocalizers.GetValue(null) as Dictionary<string, Dictionary<string, object>>;
                foreach(var kv in CardManager.ModCardLocalization)
                {
                    if (localizers.TryGetValue(kv.Key, out _))
                    {
                        //  mod优先，存在即替换
                        localizers[kv.Key] = kv.Value;
                    }
                    else
                    {
                        localizers.Add(kv.Key, kv.Value);
                    }
                }
                #endregion

            }
        }

        [HarmonyPatch(typeof(CardWidget),
            "RefreshCardImage")]
        class CardWidget_RefreshCardImage
        {
            public static void Postfix(CardWidget __instance)
            {
                if(__instance.Card.Config.Value1 == 22)
                {
                    if(!CardManager.ExtraModCards.Any(i=> { return i.id.Equals(__instance.Card.Id); }))
                    {
                        return;
                    }
                    var mc = CardManager.ExtraModCards.Where(i => { return i.id.Equals(__instance.Card.Id); }).FirstOrDefault();
                    var ttKey = mc.img_dic.Keys.FirstOrDefault();
                    var illustrator = mc.img_dic[ttKey];
                    if(!CardManager.CardImgDic.TryGetValue(ttKey,out var tt))
                    {
                        logger.LogError("未找到TT");
                    }
                    else
                    {
                        var cardImg = Traverse.Create(__instance).Field("cardImage").GetValue<RawImage>();
                        cardImg.texture = tt;
                    }

                    //logger.LogWarning(texture.name);

                    //var cardImg = Traverse.Create(__instance).Field("cardImage").GetValue<RawImage>();
                }
            }
        }



        //[HarmonyPatch(typeof(MainMenuPanel),
        //    "UI_ShowHistory")]
        //class Test_Plugin
        //{
        //    public static void Postfix()
        //    {
        //        ShowMe();
        //    }
        //}


    }
}
